package com.tuanzi.loan.business.service.settlementsystem.impl;

import com.tuanzi.loan.business.entity.family.ProductInfo;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementCompany;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementIncome;
import com.tuanzi.loan.business.entity.settlementsystem.SettlementIncomeActivity;
import com.tuanzi.loan.business.repository.settlementsystem.SettlementCompanyRepository;
import com.tuanzi.loan.business.repository.settlementsystem.SettlementIncomeActivityRepository;
import com.tuanzi.loan.business.repository.settlementsystem.SettlementIncomeRepository;
import com.tuanzi.loan.business.repository.settlementsystem.SettlementRemainRepository;
import com.tuanzi.loan.business.service.settlementsystem.BillStatus;
import com.tuanzi.loan.business.service.settlementsystem.SettlementIncomeService;
import com.tuanzi.loan.core.aspect.Debug;
import com.tuanzi.loan.core.repository.JPAAuditRepository;
import com.tuanzi.loan.core.service.BaseAuditServiceImpl;
import com.tuanzi.loan.core.vo.PageSearcher;
import com.tuanzi.loan.vo.request.settlementsystem.SettlementIncomeRequest;
import com.tuanzi.loan.vo.response.settlementsystem.SettlementIncomeResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * @author caiwanlin
 * @create 2018-08-20 14:02
 */
@Debug
@Service
@Transactional
@Retryable(value = {RetryException.class})
public class SettlementIncomeServiceImpl extends BaseAuditServiceImpl<SettlementIncome, Long> implements SettlementIncomeService {
    @Autowired
    private SettlementIncomeRepository settlementIncomeRepository;

    @Autowired
    private SettlementIncomeActivityRepository settlementIncomeActivityRepository;

    @Autowired
    private SettlementCompanyRepository settlementCompanyRepository;

    @Autowired
    private SettlementRemainRepository settlementRemainRepository;

    private ReentrantLock lock = new ReentrantLock();

    @Override
    public Page<SettlementIncomeResponse> list(PageSearcher<SettlementIncomeRequest> pageSearcher) {
        return settlementIncomeRepository.list(pageSearcher.getSearchCondition(), pageSearcher.getPageable());
    }

    @Override
    public void onSave(SettlementIncome settlementIncome, List<ProductInfo> activityList, List<Long> selectActivityIdList,Long onSeeCompanyId) {
        Long settlementIncomeId = settlementIncome.getId();
        List<SettlementIncomeActivity> collect = activityList.parallelStream().filter(a -> {
            return selectActivityIdList.contains(a.getId().toString());

        }).map(a -> {
            SettlementIncomeActivity incomeActivity = null;
            if (settlementIncomeId != null) {
                incomeActivity = settlementIncomeActivityRepository.findSettlementIncomeActivityByActivityIdAndIncomeId(a.getId(), settlementIncomeId);
            }
            if (incomeActivity == null) incomeActivity = new SettlementIncomeActivity();
            incomeActivity.setActivityId(a.getId());
            incomeActivity.setActivityName(a.getName());
            return incomeActivity;
        }).collect(Collectors.toList());

        //如果是添加，未开票状态
        if (settlementIncomeId == null) settlementIncome.setBillStatus(BillStatus.NO_BILL.index);

        //查询uv
        Integer uv = settlementIncomeActivityRepository.getUv(settlementIncome.getStartTime(),
                settlementIncome.getEndTime(), selectActivityIdList);
        if (uv == null || uv <= 0) {
            settlementIncome.setParticipateUv(0);
            settlementIncome.setUvValue(0.0);
        } else {
            settlementIncome.setParticipateUv(uv);
            settlementIncome.setUvValue(settlementIncome.getIncomeAmount() / uv);
        }

        //更新主体的消耗金额
        Double incomeAmount = null;
        Double expendAmount = null;
        SettlementCompany company = null;
        Double lastIncomeAmount = settlementIncome.getLastIncomeAmount();//最后一次消耗金额
        try {
            lock.lock();
            company = settlementCompanyRepository.findOne(settlementIncome.getCompanyId());
            expendAmount = company.getExpendAmount();
            incomeAmount = settlementIncome.getIncomeAmount();
            if (expendAmount == null) {
                company.setExpendAmount(incomeAmount);
            }
            else {
                if (settlementIncomeId == null){ //如果是添加消耗记录，公司的消耗金额 = 原始消耗金额+结算金额
                    company.setExpendAmount(expendAmount + incomeAmount);
                }
                else {//如果是修改消耗记录 ， 公司的消耗金额 = 原始消耗金额 - 最后一次结算金额 + 要更新的结算金额
                    if (onSeeCompanyId.equals(settlementIncome.getCompanyId())){//没有修改公司
//                        if (lastIncomeAmount != incomeAmount){//上次消耗金额和这次消耗金额不同才更新
                            company.setExpendAmount(expendAmount - lastIncomeAmount + incomeAmount);
//                        }
                    }
                    else {//更改公司-消耗金额的改变
                        SettlementCompany oldCompany = settlementCompanyRepository.findOne(onSeeCompanyId);
                        Double oldCompanyExpendAmount = oldCompany.getExpendAmount();
                        oldCompany.setExpendAmount(oldCompanyExpendAmount-lastIncomeAmount);
                        company.setExpendAmount(expendAmount+incomeAmount);
                        settlementCompanyRepository.save(oldCompany);
                    }
                }
            }
            settlementCompanyRepository.save(company);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        //保存消耗记录
        settlementIncome.setLastIncomeAmount(incomeAmount);
        settlementIncomeRepository.save(settlementIncome);

        //保存关联活动
        collect.forEach(s -> {
            s.setIncomeId(settlementIncome.getId());
        });
        settlementIncomeActivityRepository.save(collect);
        //插入余额记录
       /* SettlementRemain settlementRemain = null;
        if (settlementIncomeId == null){ //添加消耗记录情况
            settlementRemain = new SettlementRemain();
            settlementRemain.setCompanyId(company.getId());
            settlementRemain.setCompanyName(company.getCompanyName());
            settlementRemain.setRemainType(RemainType.EXPEND.index);
            settlementRemain.setRelateId(settlementIncome.getId());
            settlementRemain.setPrePrepayAmount(company.getPrepayAmount());
            settlementRemain.setPrepayAmount(company.getPrepayAmount());
            settlementRemain.setPreExpendAmount(expendAmount == null?0:expendAmount);
            settlementRemain.setExpendAmount(company.getExpendAmount());
            settlementRemain.setPreRemainAmount(settlementRemain.getPrePrepayAmount()-settlementRemain.getPreExpendAmount());
            settlementRemain.setRemainAmount(settlementRemain.getPrepayAmount()-settlementRemain.getExpendAmount());
            settlementRemainRepository.save(settlementRemain);
        }
        else {//更改消耗记录情况
            if (lastIncomeAmount == incomeAmount) return;//上次消耗金额和这次消耗金额不同才会执行更新操作
            settlementRemain = settlementRemainRepository
                    .findSettlementRemainByRelateIdAndRemainType(settlementIncomeId,RemainType.EXPEND.index);
            Double oldPreExpendAmount = settlementRemain.getPreExpendAmount();
            Double oldExpendAmount = settlementRemain.getExpendAmount();
            //更新消耗金额
//            settlementRemain.setPreExpendAmount(oldPreExpendAmount - lastIncomeAmount);
            settlementRemain.setExpendAmount(oldExpendAmount - lastIncomeAmount + incomeAmount);
            //更新余额
            settlementRemain.setPreRemainAmount(settlementRemain.getPrePrepayAmount()-settlementRemain.getPreExpendAmount());
            settlementRemain.setRemainAmount(settlementRemain.getPrepayAmount() - settlementRemain.getExpendAmount());
            settlementRemainRepository.save(settlementRemain);
        }
*/
    }

    @Override
    public List<SettlementIncome> findAllByBillId(Long billId) {
        return settlementIncomeRepository.findAllByBillId(billId);
    }

    @Override
    protected JPAAuditRepository<SettlementIncome, Long> getRepository() {
        return settlementIncomeRepository;
    }
}
